package paperfly.game.state;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;

import paperfly.game.Player;
import paperfly.game.handler.EnterGameHandler;

import com.jme.image.Texture;
import com.jme.input.ChaseCamera;
import com.jme.input.thirdperson.ThirdPersonMouseLook;
import com.jme.light.DirectionalLight;
import com.jme.math.FastMath;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.state.LightState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.game.state.CameraGameState;
import com.jmex.game.state.GameStateManager;

public class EnterGameState extends CameraGameState {
	private static final String PATH_PISTA = "models/jme/pista.jme";
	private Player player;
	private Skybox sky;
	private Node pista;
	private EnterGameHandler input;
	private ChaseCamera chaser;

	public EnterGameState(Player player) {
		super("entering");

		this.player = player;
		try {
			this.pista = (Node) BinaryImporter.getInstance().load(
					new File(PATH_PISTA));
		} catch (IOException e) {
			e.printStackTrace();
		}
		buildSky();
		placePista();
		placePlayer();
		createInput();
		buildChaseCamera();
		buildLight();
		rootNode.updateRenderState();
		rootNode.updateGeometricState(0, true);
	}

	/**
	 * @throws MalformedURLException
	 */
	private void buildSky() {
		sky = new Skybox("ceu", 50, 30, 50);
		String dir = "images/skybox/entardecer";
		try {
			Texture north = TextureManager.loadTexture(new File(dir + "/1.jpg")
					.toURL(), Texture.MM_LINEAR, Texture.FM_LINEAR);
			Texture south = TextureManager.loadTexture(new File(dir + "/3.jpg")
					.toURL(), Texture.MM_LINEAR, Texture.FM_LINEAR);
			Texture east = TextureManager.loadTexture(new File(dir + "/2.jpg")
					.toURL(), Texture.MM_LINEAR, Texture.FM_LINEAR);
			Texture west = TextureManager.loadTexture(new File(dir + "/4.jpg")
					.toURL(), Texture.MM_LINEAR, Texture.FM_LINEAR);
			Texture up = TextureManager.loadTexture(new File(dir + "/6.jpg")
					.toURL(), Texture.MM_LINEAR, Texture.FM_LINEAR);
			Texture down = TextureManager.loadTexture(new File(
					"images/textures/grama.png").toURL(), Texture.MM_LINEAR,
					Texture.FM_LINEAR);
			sky.setTexture(Skybox.NORTH, north);
			sky.setTexture(Skybox.WEST, west);
			sky.setTexture(Skybox.SOUTH, south);
			sky.setTexture(Skybox.EAST, east);
			sky.setTexture(Skybox.DOWN, down);
			sky.setTexture(Skybox.UP, up);
			sky.preloadTextures();
		} catch (MalformedURLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		rootNode.attachChild(sky);
		rootNode.updateRenderState();
	}

	private void buildLight() {
		DirectionalLight light = new DirectionalLight();
		light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
		light.setAmbient(new ColorRGBA(1f, 1f, 1f, 1.0f));
		light.setDirection(new Vector3f(1, -1, 0));
		light.setEnabled(true);

		/** Attach the light to a lightState and the lightState to rootNode. */
		LightState lightState = DisplaySystem.getDisplaySystem().getRenderer()
				.createLightState();
		lightState.setEnabled(true);
		lightState.attach(light);
		rootNode.setRenderState(lightState);
	}

	private void createInput() {
		input = new EnterGameHandler(player);
	}

	private void placePlayer() {
		player.setLocalTranslation(new Vector3f(0, -97, -210));
		player.setLocalScale(0.25f);
		player.setVelocity(0);
		player.updateRenderState();
		rootNode.attachChild(player);
		rootNode.updateRenderState();
	}

	private void placePista() {
		pista.setLocalTranslation(new Vector3f(0, -100, 0));
		pista.setLocalScale(new Vector3f(1, 1, 5));
		rootNode.attachChild(pista);
		rootNode.updateRenderState();
	}

	@Override
	protected void stateRender(float tpf) {
		rootNode.updateGeometricState(tpf, false);
		rootNode.updateRenderState();
		super.stateRender(tpf);
	}

	private void buildChaseCamera() {
		HashMap<String, Object> props = new HashMap<String, Object>();
		props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "6");
		props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "3");
		props.put(ThirdPersonMouseLook.PROP_MAXASCENT, "" + 45
				* FastMath.DEG_TO_RAD);
		props.put(ChaseCamera.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0,
				30 * FastMath.DEG_TO_RAD));
		props.put(ChaseCamera.PROP_DAMPINGK, "4");
		props.put(ChaseCamera.PROP_SPRINGK, "9");
		props.put(ChaseCamera.PROP_STAYBEHINDTARGET, new Boolean(false));
		chaser = new ChaseCamera(cam, player, props);
		chaser.setMaxDistance(10);
		chaser.setMinDistance(5);
	}

	@Override
	protected void stateUpdate(float tpf) {
		float velocity = player.getVelocity();
		if (player.vehicleIsMoving() && velocity < player.getMaxSpeed()) {
			player.accelerate(tpf * 2);
		}
		verificaPosicao();
		sky.setLocalTranslation(cam.getLocation());
		player.update(tpf);
		input.update(tpf);
		chaser.update(tpf);
		super.stateUpdate(tpf);
	}

	private void verificaPosicao() {
		Vector3f posicaoAviao = player.getLocalTranslation();
		Vector3f posicaoPista = pista.getLocalTranslation();

		if ((posicaoAviao.y - 2) < posicaoPista.y) {
			posicaoAviao.setY(posicaoPista.y + 2);
		}
		if (player.vehicleIsMoving() && posicaoAviao.y > posicaoPista.y + 30) {
			input.ativarRotacoes();
			InGameState inGame = new InGameState("in",player, chaser, input);
			GameStateManager.getInstance().attachChild(inGame);
			inGame.setActive(true);
			setActive(false);
		}
	}
}
